package com.nanbei.a01;

import com.nanbei.a01.component.*;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultSingletonBeanRegistry;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.MessageSource;
import org.springframework.core.io.Resource;
import org.springframework.scheduling.annotation.EnableAsync;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Locale;
import java.util.Map;

/**
 * @ClassDescription:
 * @JdkVersion: 1.8
 * @Author: libs
 * @Created: 2024/9/4 15:27
 */
@SpringBootApplication
@EnableAsync
public class SpringMainApplication {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {
        // 返回的对象就是容器
        ConfigurableApplicationContext context = SpringApplication.run(SpringMainApplication.class, args);

        /*
            1.到底什么是BeanFactory
                    -它是ApplicationContext 的父接口
                    -它才是Spring 的核心容器，主要的ApplicationContext实现 都【组合】了它的功能
         */
        System.out.println(context);

        /*
            2.BeanFactory 能干点啥
                    -表面上只有 getBean
                    -实际上控制反转、基本的依赖注入、直至Bean 的生命周期的各种功能，都由它的实现类提供
         */
        // 获取所有单例bean集和
        Field singletonObjects = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
        // 允许访问 private 字段
        singletonObjects.setAccessible(true);
        // 获取提取表示字段的值的对象（beanFactory）
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        Map<String, Object> map = (Map<String, Object>) singletonObjects.get(beanFactory);
        // 只打印 component 开头的bean
        map.entrySet().stream().filter(e -> e.getKey().startsWith("component"))
                .forEach(e->{
                    System.out.println(e.getKey()+"===="+e.getValue());
                });

        /*
            Application 比 BeanFactory 多点啥
         */
        // 消息国际化
        MessageSource messageSource = context.getBean(MessageSource.class);
        System.out.println("MessageSource bean: " + messageSource);
        System.out.println(context.getMessage("hii",null,Locale.CHINA));
        System.out.println(context.getMessage("hii",null,Locale.ENGLISH));


        /*
            classpath 在类路径下找
            classpath* 也可以在jar包中找
         */
        // 查找资源文件
        Resource[] resources = context.getResources("classpath*:application.yml");
        for (Resource resource : resources) {
            System.out.println(resource);
        }

        resources = context.getResources("classpath*:META-INF/spring.factories");
        for (Resource resource : resources) {
            System.out.println(resource);
        }

        // 获取当前应用程序的 环境配置 ,它允许你访问当前运行环境中的属性值、配置文件和环境变量等信息。
        System.out.println(context.getEnvironment().getProperty("java_home"));
        System.out.println(context.getEnvironment().getProperty("server.port"));
        System.out.println(context.getEnvironment().getProperty("spring.application.name"));


        // 发布事件
        // context.publishEvent(new UserRegisteredEvent(context,"nihao"));
        Component1 bean = context.getBean(Component1.class);
        bean.register();

    }
}
